/*! \file TcpServer.h holds the Tcp server functionality. */
#ifndef __TCP_SERVER_H_INCLUDED__
#define __TCP_SERVER_H_INCLUDED__

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include "TcpSession.h"

using boost::asio::ip::tcp;

class TcpServer
{
public:
	typedef boost::function< TcpSessionPtr ( boost::asio::io_service & )> SessionFactory;

	TcpServer(boost::asio::io_service& io_service, short port, SessionFactory f) :  io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), m_SessionFactory(f)
	{
		startAccept();
	}

	void handle_accept(TcpSessionPtr new_session, const boost::system::error_code& error)
	{
		if (!error)
		{
			new_session->start();
			startAccept();
		}
	}

protected:
	void startAccept ( )
	{
		TcpSessionPtr new_session ( m_SessionFactory(io_service_) ) ;
		acceptor_.async_accept(new_session->socket(),
			boost::bind(&TcpServer::handle_accept, this, new_session,
			  boost::asio::placeholders::error));
	}


private:
  boost::asio::io_service& io_service_;
  tcp::acceptor acceptor_;
  SessionFactory m_SessionFactory;
};




#endif